<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
    //21-04-28  
    //21-11-19 补充 
    //对比 map forEach filter等数组方法 reduce比他们更加强大 
    //注意 reduce()对于空数组是不会执行回调函数的 
    
    //demo1  
    //reduceRight() 和 reduce 
        //两个方法都会实现循环数组的所有项(即累加器) 然后构建一个最终返回的值  
        //reduce()方法从数组的      第一项开始      逐个循环到最后  
        //reduceRight()则从数组的   最后一项开始    向前遍历到第一项    
        //4个参数   1前一个值 2当前值 3项的索引 4数组对象即本身 
        var values = [1,2,3,4,5];
        var sum = values.reduceRight(function(prev,cur,index,array){
            return prve + cur;
        },10)   // 注意数组一开始加了一个初始值10  可以不设置默认 
        console.log(sum); // 25 


    //语法参数  
    // reduce 接收两个参数 回调函数和初始值 初始值是可选的 回调函数接收4个参数 
    // arr.reduce(function(prew,cur,index,arr),init);
    /*
      积累值 参1 上一次调用回调返回的值 && 提供的初始值
      当前值 参2 数组中当前被处理的元素 
      当前标 参3 当前元素在数组中的索引 
    当前数组 参4 调用的数组 
       参5 传递给函数的初始值 
    */        


    //累加器带输出是值 8
    var arr1 = [1,2,3,4];
    var sum = arr1.reduce((pre,item)=>{
        console.log(pre)    // 10 11 13 16 20
        console.log(item)   // 1 2 3 4 
        return pre+item

    },10)
    console.log(sum)  //20 

    var arr1 = [1,2,3,4];
    var sum = arr1.reduce((pre,item)=>{
        return pre+item
    })
    console.log(sum)  //10不带初始值 


    //reduce数组去重 
    var arr2 = [1,2,2,2,4,5,6,6,6,6];
    var sum1 = arr2.reduce((acc,cur)=>{
        if(!(acc.includes(cur))){
            acc.push(cur);
        }
        return acc
    },[])
    console.log(sum1)   // 1 2 4 5 6 


    //reduce求数组最大值 
    var arr3 = [1,2,333333333];
    var sum2 = arr3.reduce((prev,cur)=>{
        return Math.max(prev,cur)
    })
    console.log(sum2)  //333333333


    //reduce二维数组转一维数组
    var arr4 = [[1,2],[3,4],[5,6]];
    var once = arr4.reduce((acc,cur)=>{
        return acc.concat(cur)
    })
    console.log(once)   //1 2 3 4 5 6 


    //reduce 对象里面的属性求和  
    var arr5 = [
        {a:"aaaa",money:100},
        {b:"bbbb",money:100},
        {c:"cccc",money:200},
        {d:"dddd",money:100},
    ]
    var sum4 = arr5.reduce((pre,cur)=>{
        return cur.money + pre 
    },0)
    console.log(sum4)  //500  


    //面试题 
    //计算数组中某个值的出现次数
    const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a), 0);
    countOccurrences([2,4,6,2,5,2], 2)  // 3 
    countOccurrences([1,4,6,2,5,6], 6)  // 2

  
    // 数组对象 分类 
    let obj = [
        {name: 'Alice', job: 'Data Analyst', country: 'AU'},
        {name: 'Bob', job: 'Pilot', country: 'US'},
        {name: 'Lewis', job: 'Pilot', country: 'US'},
        {name: 'Karen', job: 'Software Eng', country: 'CA'},
        {name: 'Jona', job: 'Painter', country: 'CA'},
        {name: 'Jeremy', job: 'Artist', country: 'SP'},
    ]
    let ppl = obj.reduce((group, curP) => {
        
        let newkey = curP['country']
            if(!group[newkey]){
                group[newkey]=[]
            }
        group[newkey].push(curP)
            return group
    }, [])  
    console.log(ppl);
    /* 
        [AU: Array(1), US: Array(2), CA: Array(2), SP: Array(1)]
        AU: Array(1)
            0: {name: 'Alice', job: 'Data Analyst', country: 'AU'}
        CA: Array(2)
            0: {name: 'Karen', job: 'Software Eng', country: 'CA'}
            1: {name: 'Jona', job: 'Painter', country: 'CA'}
        SP: Array(1)
            0: {name: 'Jeremy', job: 'Artist', country: 'SP'}
        US: Array(2)
            0: {name: 'Bob', job: 'Pilot', country: 'US'}
            1: {name: 'Lewis', job: 'Pilot', country: 'US'}
    */


    /* _数组转树 
    [ 
        { id: "01", name: "张大大", pid: "", job: "项目经理" },
        { id: "02", name: "小亮", pid: "01", job: "产品leader" },
        { id: "03", name: "小丽", pid: "02", job: "产品经理" },
        { id: "04", name: "大光", pid: "02", job: "产品经理" },
        ]
        // ----------------- 转换为 -----------------------------
        [
            { label: '项目经理-张大大', children: [
                { label: '产品leader-小亮', children: [
                    { label: '产品经理-小丽'},
                    { label: '产品经理-大光'}
                ]}
            ]}
        ]
    // 思路  
           1 JSON.parse(JSON.stringify) 实现数组深拷贝 
           2 数组foreEach 和 push 
           3 || 短路判断 
           4 引用数据类型*/
    // 解题 
   var data = [ 
        { id: "01", name: "张大大", pid: "", job: "项目经理" },
        { id: "02", name: "小亮", pid: "01", job: "产品leader" },
        { id: "03", name: "小丽", pid: "02", job: "产品经理" },
        { id: "04", name: "大光", pid: "02", job: "产品经理" },
        ]
    function arrTree(data){
        console.log(data,"___res");
        let nData = JSON.parse(JSON.stringify(data))  // 数组深拷贝 避免影响数据源 
        console.log(nData,'-------');
        let result = []                               // 存放 以 抛出  
        let map = {}

        nData.forEach(item => {                       // 循环 把每一项的引用 放到map对象里面 
            // console.log(item)_nData_i 
            map[item.id] = item    
            // delete item.id // id 已经保存在了map.key里 可以删掉
        });
        // console.log(map) _map 已存值  
        nData.forEach((item)=>{                       // 再次循环 确定值的 流向  
            let parent = map[item.pid];
            // 下面是数据处理 
            item.lable = item.job + '-' + item.name
            // delete item.pid
            // delete item.name
            // delete item.job
            console.log(item.lable,'0')
            if (parent) {
            // 如果 map[item.pid] 有值 则 parent 为 item 的父级
            // 判断 parent 里有无children 如果没有则创建 如果有则直接把 item push到children里
            (parent.children || (parent.children = [])).push(item);
            } else {
            // 如果 map[item.pid] 找不到值 说明此 item 为 第一级
            result.push(item);
            }
        })
        return result
    }
    arrTree(data)
    
    











</script>